package com.enjoyor.soa.traffic.frame.logger.impl;

import com.enjoyor.soa.traffic.frame.constant.AuthConstant;
import com.enjoyor.soa.traffic.frame.domain.PubLogNorm;
import com.enjoyor.soa.traffic.frame.logger.IPubLogNormMapper;
import com.enjoyor.soa.traffic.frame.security.bean.dto.UserDto;
import com.enjoyor.soa.traffic.frame.support.mybatis.mapper.impl.BaseMapper;
import com.enjoyor.soa.traffic.frame.support.redis.IRedisTool;
import com.enjoyor.soa.traffic.util.enums.log.LogInfoDic;
import com.enjoyor.soa.traffic.util.helper.JsonHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;
import com.enjoyor.soa.traffic.util.helper.UserLogHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Transactional
public class PubLogNormMapper extends BaseMapper<PubLogNorm> implements IPubLogNormMapper {

    @Autowired
    private IRedisTool redisTool;



    @Override
    public void insert(PubLogNorm log) {
        log.setLogId(String.valueOf(System.nanoTime()));
        log.setLogTime(new Date());
        super.insert(log);
    }


    @Override
    public void saveNoramlLogInfo(String sysName,String logModular,String token, String transType) {
    	PubLogNorm log = this.getBaseLogInfo(sysName, logModular, token, transType);
        this.insert(log);
    }

    @Override
    public void saveNoramlLogInfo(PubLogNorm log) {
        this.insert(log);
    }

    /**
     * 操作日志记录（封装方法）
     * @param sysName
     * @param moduleInfo
     * @param token
     * @param operateType
     * @param beforeObject
     * @param afterObject
     * @param primyKeyName
     */
    @Override
    public void saveLogInfo(String sysName, String moduleInfo, String token, String operateType, Object beforeObject, Object afterObject, String primyKeyName) {
        PubLogNorm log = getBaseLogInfo(sysName, moduleInfo, token, operateType);
        log = checkTransType(operateType,log,moduleInfo, token,beforeObject,afterObject,primyKeyName);
        saveNoramlLogInfo(log);
    }

    public void saveLogInfo(String sysName, String moduleInfo, String token, String operateType, Exception ex) {
        PubLogNorm log = getBaseLogInfo(sysName, moduleInfo, token, operateType);
        log.setLogResult(moduleInfo+"失败:"+ex.getMessage());
        saveNoramlLogInfo(log);
    }




    @Override
    public PubLogNorm getBaseLogInfo(String sysName, String logModular, String token, String transType) throws NullPointerException {
        PubLogNorm log = new PubLogNorm();
        UserDto user = new UserDto();
        if (token != null && !token.isEmpty()) {
            user = this.getCurrentUser(token);
        } else throw new NullPointerException("token为空");
        log = checkTransType(transType,log);
        log.setLogIp(user.getAddrIP());
        log.setLogUser(user.getSsoUserName());
        log.setPersonId(user.getPersonId());
        log.setOrgId(user.getOrgId());
        log.setOrgName(user.getOrgName());
        log.setLogModular(logModular);
        log.setLogMac(user.getAddrMAC());
        log.setLogSysName(sysName);
        log.setLogId(TimeHelper.getUniqueId(8));
        log.setLogLevel(LogInfoDic.LOG_LEVEL_ENUM.LOG_NORMAL.getCode());
        log.setLogLevelName(LogInfoDic.LOG_LEVEL_ENUM.LOG_NORMAL.getMessage());
        log.setLogClass(LogInfoDic.LOG_CLASS_ENUM.OPERATOR.getCode());
        log.setLogClassName(LogInfoDic.LOG_CLASS_ENUM.OPERATOR.getMessage());
        return log;
    }

    private PubLogNorm checkTransType(String transType, PubLogNorm log,String moduleInfo, String token,Object beforeObject, Object afterObject, String primyKeyName) {
        switch (transType) {
            case "select": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_SELECT.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_SELECT.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                break;
            }
            case "insert": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(StringUtils.isBlank(moduleInfo)||StringUtils.isBlank(primyKeyName)||afterObject==null){
                    break;
                }
                String logContent=moduleInfo+"新增编号["+primyKeyName+"："+UserLogHelper.getFiledValue(afterObject,primyKeyName)+"]";
                log.setContent(logContent);
                log.setContentAfter(UserLogHelper.castToString(afterObject));
                break;
            }
            case "batchInsert": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_INSERT.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(StringUtils.isBlank(moduleInfo)||afterObject==null){
                    break;
                }
                String logContent=moduleInfo+"批量新增";
                log.setContent(logContent);
                log.setContentAfter(UserLogHelper.castToString(afterObject));
                break;
            }
            case "update": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(beforeObject!=null&&afterObject!=null&&moduleInfo!=null){
                    String logContent = UserLogHelper.getUpdateContent(beforeObject, afterObject, "rltId", moduleInfo, true);
                    log.setContent(logContent);
                    log.setContentAfter(UserLogHelper.castToString(afterObject));
                    log.setContentBefore(UserLogHelper.castToString(beforeObject));
                }
                break;
            }
            case "batchUpdate": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_UPDATE.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(beforeObject!=null&&afterObject!=null&&moduleInfo!=null){
                    String logContent = "批量修改";
                    log.setContent(logContent);
                    log.setContentAfter(UserLogHelper.castToString(afterObject));
                    log.setContentBefore(UserLogHelper.castToString(beforeObject));
                }
                break;
            }
            case "delete": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_DELETE.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_DELETE.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(StringUtils.isBlank(moduleInfo)||StringUtils.isBlank(primyKeyName)||beforeObject==null){
                    break;
                }
                String logContent=moduleInfo+"删除编号["+primyKeyName+"："+UserLogHelper.getFiledValue(beforeObject,primyKeyName)+"]";
                log.setContent(logContent);
                log.setContentBefore(UserLogHelper.castToString(beforeObject));
                break;
            }
            case "batchDelete": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_DELETE.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_DELETE.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                if(StringUtils.isBlank(moduleInfo)||beforeObject==null){
                    break;
                }
                String logContent=moduleInfo+"批量删除";
                log.setContent(logContent);
                log.setContentBefore(UserLogHelper.castToString(beforeObject));
                break;
            }
            case "export": {
                log.setTransType(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_EXPORT.getCode());
                log.setTransTypeName(LogInfoDic.LOG_TRANSTYPE_ENUM.TRANSTYPE_EXPORT.getMessage());
                log.setLogResult(log.getTransTypeName() + "成功");
                break;
            }
        }
        return log;
    }

    private PubLogNorm checkTransType(String transType, PubLogNorm log) {
        return checkTransType(transType, log,null,null,null,null,null);
    }

    private UserDto getCurrentUser(String token) {
        String authorizeStr = redisTool.get(AuthConstant.TOKEN + token);
        if (authorizeStr != null && !StringUtils.isBlank(authorizeStr)) {
            UserDto currentUser = (UserDto) JsonHelper.jsonToObject(authorizeStr, UserDto.class);
            return currentUser;
        }
        return null;
    }
}
